/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package im.eventservice;
import im.general.AbstractListenBehaviour;
import im.general.Config;
import im.messages.ClusteringMsgPayload;
import im.node.MobileNodeInfo;
import jade.core.AID;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Gnaskky
 */
public class ClusterJoinNotifyBehaviour extends AbstractListenBehaviour {

    private EventServiceAgent es;

    ClusterJoinNotifyBehaviour(EventServiceAgent es) throws Exception {
        this.es = es;
        ACLMessage wrap_msg = new ACLMessage( ACLMessage.CONFIRM );
        wrap_msg.addUserDefinedParameter( Config.IM_MSG_TYPE, Config.SRVC_JOIN_NOTIFY_MSG);
        this.mt = MessageTemplate.MatchCustom(wrap_msg, true );
    }

    @Override
    protected void handleMessage(ACLMessage in_msg) {
        try {
            //System.out.println("ho ricevuto un messaggio di JOIN_SERVICE_REQUEST! ^^");
            /* VEDERE:
             * gestione DB cluster
             * status handling
             * */
            /*
            add_to_local_db;
            ES.notify_join(isNewJoin);
            get_ack(ES);
            send_ack(CLI);
            if(meetClusterizeConditions())
            clusterize();
             * */
            /*String ch = in_msg.getSender().getName();
            String es = in_msg.getSender().getName();*/
            ClusteringMsgPayload msg_pl = (ClusteringMsgPayload) in_msg.getContentObject();

            this.es.updateHead(in_msg.getSender().getLocalName(), msg_pl.getStatus());
            //MobileNodeInfo mn_info = (MobileNodeInfo) in_msg.getContentObject();
            MobileNodeInfo mn_info = (MobileNodeInfo) msg_pl.getPayload();

            if( Config.TRACE_LVL > Config.ULTRA_TR_LVL )
                System.out.println("[ClusterJoinNotifyBe]\tSRVC_JOIN_NOTIFY_MSG [MN CH]     "
                    +  mn_info.getNode_localname() + "\t" + mn_info.getCh_name() );
            
            MobileNodeInfo check_oldinfo = es.getNodeInfo(mn_info.getNode_name());

            // if we have yet a node description we need to update that info and propagate changes to the network
            if( check_oldinfo != null )
                notify_unjoin(check_oldinfo);

            es.addNode(mn_info.getNode_name(), mn_info);
            // ES.notify_join(isNewJoin);
            /* BaseMessage out_msg = new BaseMessage( BaseMessage.NOTIFY_JOIN );
            out_msg.addReceiver(new AID(Config.EVENT_SERVICE_NAME,AID.ISLOCALNAME));
            out_msg.addUserDefinedParameter("MN", mn);
            //cli_CH.join_request(isNewJoin=true);g
             * */
            /*
            ACLMessage jntfy_msg = new ACLMessage(ACLMessage.REQUEST);
            jntfy_msg.addUserDefinedParameter(Config.IM_MSG_TYPE, Config.SRVC_JOIN_NOTIFY_MSG);
            jntfy_msg.addReceiver(new AID(mn_info.getNode_name(), AID.ISLOCALNAME));
            //jntfy_msg.setContentObject(mn_info);
            ch.sendMessage(jntfy_msg);
            if (ch.checkClusterizeConditions()) {
                this.clusterize();
            }
             * */
        } catch (Exception ex) {
            Logger.getLogger(ClusterJoinNotifyBehaviour.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
        }
    }

    protected void notify_unjoin(MobileNodeInfo old_info ) {

            //NOTE: we need this check for stealing reasons
            if( !es.heads.containsKey(old_info.getCh_name()))
                return;

            es.updateHeadUnjoin(old_info.getCh_name());

            if( Config.TRACE_LVL > Config.ULTRA_TR_LVL )
                System.out.println("[ClusterJoinNotifyBe]\tUNJOIN notify to\t\t " + old_info.getCh_name());

            ACLMessage unj_msg = new ACLMessage(ACLMessage.PROPAGATE);
            unj_msg.addUserDefinedParameter(Config.IM_MSG_TYPE, Config.SRVC_UNJOIN_NOTIFY_MSG);
            unj_msg.addUserDefinedParameter(Config.OLD_MN_NAME, old_info.getNode_name());
            unj_msg.addReceiver(new AID(old_info.getCh_name(), AID.ISLOCALNAME));
            es.sendMessage(unj_msg);
    }

}
